home *** CD-ROM | disk | FTP | other *** search
-
- ;; This file sets up machinery to build a doc string file from
- ;; a number of lisp files. Then it allows building of key pointers
- ;; into that file. These can be used to complete and view documentation
- ;; in emacs. I have tried to emulate the usage pattern of the tags facility
- ;; in order to make the doc facility easier to use.
- ;; edoc <--> etags
- ;; DOC <--> TAGS
- ;; visit-doc-file <--> visit-tags-table
- ;; C-h d <--> M-.
-
- ;; To create the doc strings file use edoc.
- ;; Usage:
- ;; % edoc *.lisp
- ;; This creates a DOC file and a DOC-keys.el file.
- ;; Normally comments which appear where a doc string would have
- ;; been, will be used instead of the doc string. Also comments
- ;; preceding or following a defvar will be used depending
- ;; on the setting of the variable comments-for-defvar.
- ;; You may set that variable in a .edoc file.
- ;; For c files you may use the appropriate primitive in emacs/etc
- ;; in order to create the DOC file.
- ;; For a lisp system for which you do not have sources (why are you using it!),
- ;; you may build a DOC file using the common lisp function doc-file
- ;; provided in this file. You must then use the snarf-doc command, to
- ;; build the keys into the DOC file you have just created.
- ;; You may concatenate two DOC files. Again you must use snarf-doc,
- ;; to build the keys.
-
- ;; To use the documentation so created do
- ;; M-x visit-doc-file to set up for using a particular DOC file.
- ;; Then C-hd (find-doc) will allow you to query the doc data base.
-
-
- (defvar comments-for-defvar 'after)
- ;; If nil only use comments inside the defvar,
- ;; If the symbol 'after use comment following, and if 'before
- ;; use the comment before.
-
- (defvar doc-start "")
- ;; The special string which starts each doc record. key used
- (defvar doc-key-length 1)
- ;; The length of the description immediately following doc-start
- ;; which says if this is a function,...: This field contains
- ;; F for function or M for macro V for variable,...
-
-
- (defvar find-doc-name)
- (defvar find-doc-args)
- ;Used internally by find-doc-args.
-
- (defvar include-all-functions-and-args nil)
- ;;If t all functions, not just those with documentation, will be included.
- (defvar include-args t)
- ;;If t a macro or function's args will be included.
-
- ;;Set up the common lisp syntax table.
- (defvar common-lisp-syntax-table (copy-syntax-table lisp-mode-syntax-table))
-
- (let* ((const "!$%&*+-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz[]^_{}~")
- (i 0))
- (while (< i (length const))
- (modify-syntax-entry (aref const i) "w" common-lisp-syntax-table)
- (setq i (1+ i))))
-
-
- (defun forward-over-white()
- (while (looking-at "[ \n]")
- (forward-char 1)))
-
- (defun back-over-white()
- (let (tem)
- (while (looking-at "[ \n]")
- (setq tem t)
- (forward-char -1))
- (if tem (forward-char 1))
- ))
-
-
- (defun make-doc (file out)
- "Create documentation for file"
- (find-file file)
- (let ((file-buf (current-buffer)))
- (if buffer-read-only (toggle-read-only))
- (goto-char (point-min))
- (set-syntax-table common-lisp-syntax-table)
- (setq doc-buf (generate-new-buffer "doc-buf"))
- (while (re-search-forward "^(def" nil t)
- (condition-case er
- (parse-one-def out)
- (error (end-of-line) er)))
- (set-buffer-modified-p nil)
- (kill-buffer file-buf)
- doc-buf
-
- ))
-
-
- (defun make-all-doc (out-file file-list)
- ;Write doc strings to OUT-FILE for all files in FILE-LIST.
- ;Currently lisp syntax is assumed for files in file-list.
-
- (if (file-exists-p out-file) (delete-file out-file))
- (while file-list
- (setq file (car file-list))
- (message (format "for %s.."file))
- (setq buf (make-doc file nil))
- (switch-to-buffer buf)
- (append-to-file (point-min) (point-max) out-file)
- (kill-buffer buf)
- (setq file-list (cdr file-list))
- ))
-
- (global-set-key "d" 'find-doc)
- (global-set-key "/" 'apropos-doc)
-
-
- (defun apropos-doc (test)
- (interactive "sApropos doc string: ")
- (require-doc-file)
- (let (ans (alist my-lisp-doc))
- (while alist
- (cond ((string-match test (car (car alist)))
- (setq ans (cons (car (car alist)) ans))))
- (setq alist (cdr alist)))
- (with-output-to-temp-buffer "*Completions*"
- (display-completion-list ans))))
-
-
-
- (defun string-next-sexp (pt)
- (save-excursion
- (goto-char pt)
- (let ((beg pt)
- (end (progn (forward-sexp 1) (point)))
- )
- (goto-char beg)
- (cond ((and (looking-at "(")
- (re-search-forward "\\b&aux" end t))
- (forward-char (- (length "&aux")))
- (skip-chars-backward " \n")
- (concat (buffer-substring beg (point))
- ")"))
- (t(buffer-substring beg end))))))
-
-
-
-
-
- (defun skip-to-doc (type)
- (forward-char 2)
- (setq find-doc-name (progn (forward-sexp 1)
- (forward-over-white) (point)))
- (cond ((equal type "V")
- (forward-sexp 1) ;skip the name
- (forward-over-white)
- (or (looking-at ")") (forward-sexp 1))
- (forward-over-white)
- (cond ((and comments-for-defvar
- (looking-at ")"))
- (cond ((eq comments-for-defvar 'after)
- (forward-char 1)
- (forward-over-white))
- ((eq comments-for-defvar 'before)
- (goto-char find-doc-name)
- (previous-line 1)
- (back-over-white)
- (beginning-of-line)
-
- ))))
- (setq find-doc-args nil))
- (t
- (setq find-doc-args
- (progn (forward-sexp 1)(forward-over-white) (point)))
- ;skip name
-
- (forward-sexp 1) (forward-over-white) ;skip the args
- ))
- (read-doc type)
- )
-
- (defun parse-one-def (out)
- (let (name)
- (beginning-of-line)
- (cond ((looking-at "(defun")
- (skip-to-doc "F"))
- ((looking-at "(defmacro")
- (skip-to-doc "M"))
- ((or (looking-at "(defvar")
- (looking-at "(defconstant")
- (looking-at "(defparameter"))
- (skip-to-doc "V"))
- )
- (end-of-line)
- ))
-
- (defvar find-doc-comment-start nil)
- (defun mark-very-long-comment ()
- (interactive)
- ; (mm "call mark comment at %d" (point))
-
- (setq comment-start (or find-doc-comment-start comment-start))
- (let ((at (point)))
- (beginning-of-line)
- (while(and (not (eobp))
- (or (looking-at comment-start)
- (looking-at "[ ]*\n")
- ))
- (forward-line 1))
- (back-over-white)
- (set-mark (point))
- (goto-char at)
- (while(and (not (bobp))
- (or (looking-at comment-start)
- (looking-at "[ ]*\n")
- ))
- (forward-line -1))
- (if (not (looking-at comment-start))(forward-line 1))
- (forward-over-white)
- ))
-
-
- (defmacro mm (&rest b)
- (list 'progn (list 'message (cons 'format b)) '(sleep-for 1)))
- ;;narrows to the long-comment, and removes the ;
- (defun copy-long-comment (to-buf)
- (mark-very-long-comment)
- (let ((beg (min (dot) (mark)))
- (end (max (dot) (mark))) (n 0)m)
- ; (mm "Beg %d end %d" beg end)
- (narrow-to-region beg end)
- (goto-char (point-min))
- (forward-over-white)
- (let ((tem (point)))
- ; (mm "check at %d" tem)
- (while (looking-at ";")
- (forward-char 1))
- (setq n (- (point) tem)))
- (goto-char (point-min))
- (while (not (eobp))
- (setq m n)
- (while (> m 0)
- (cond (;(looking-at ";")
- (looking-at comment-start)
- (delete-char 1)
- (cond ((looking-at " ")(delete-char 1)(setq m 0)))
- (setq m (- m 1)))
- (t (setq m 0))))
- (forward-line 1)))
- (my-copy-to-buffer
- doc-buf (point-min) (point-max))
- (widen)
- )
-
- (defun my-copy-to-buffer (buf beg end)
- (let ((tem (current-buffer)))
- (switch-to-buffer buf)
- (insert-buffer-substring tem beg end)
- (switch-to-buffer tem)))
-
-
- (defun write-doc (string)
- (let ((buf (current-buffer)))
- (switch-to-buffer doc-buf)
- (goto-char (point-max))
- (insert string)
- (switch-to-buffer buf)))
-
- (defun write-doc-string-begin (type)
- (let ((name (string-next-sexp find-doc-name))
- (args (if find-doc-args (string-next-sexp find-doc-args))))
- (let ((buf (current-buffer)))
- (switch-to-buffer doc-buf)
- (goto-char (point-max))
- (insert doc-start type name)
- (insert (cdr (assoc type
- '(("F" . "\n Function ")
- ("M" . "\n Macro ")
- ("T" . "\n Topic ")
- ("V" . "\n Variable: ")))))
- (cond ((and args include-args)
- (insert "Args: " args "\n"))
- (t (insert "\n")))
- (switch-to-buffer buf)
- )))
-
- (defun read-doc (type)
- "Reads the documentation and puts in doc file"
- (skip-chars-forward " \n" )
- (cond ((looking-at comment-start)
- (write-doc-string-begin type)
- (copy-long-comment doc-buf))
- ((looking-at "\"")
- (let ((tem (point))
- (end (progn (forward-sexp 1)(point))))
- (write-doc-string-begin type)
- (my-copy-to-buffer doc-buf (+ 1 tem) (- end 1))))
- (include-all-functions-and-args
- (write-doc-string-begin type))))
-
-
- (defun snarf-doc (file)
- "Takes a doc string file, and records the pointers into that file.
- It writes out a list of doc pointers into file-keys.el. The list is suitable
- for the find-doc command."
- (interactive "FMake -keys.el for file: ")
- (find-file file)
- (set-syntax-table common-lisp-syntax-table)
- (goto-char (point-min))
- (let (tem lis)
- (while (search-forward doc-start nil t)
- (setq tem (point))
- (setq lis (cons
- (cons (buffer-substring (setq tem (+ doc-key-length tem))
- (progn (forward-sexp 1) (point)))
- (- tem 1)
- )
- lis)))
- (let ((buf (generate-new-buffer "-keys.el"))(tem lis))
- (switch-to-buffer buf)
- (insert "(setq my-lisp-doc '(")
- (while tem
- (prin1 (car tem) buf)
- (terpri buf)
- (setq tem (cdr tem))
- )
- (insert "))")
- (write-file (concat file "-keys.el")))
- (setq my-lisp-doc lis)))
-
- (defvar find-doc-buffer nil)
- ; buffer where the lisp documentation lives
-
- (defvar doc-file-name nil)
- ; File name of the current doc file. Usually ../DOC should be used
- ; and ../DOC-keys.el will hold the keys to the file.
-
-
- (defun visit-doc-file (file)
- (interactive (list (read-file-name "Visit doc table: (default DOC) "
- default-directory
- (concat default-directory "DOC")
- t)))
- (setq file (expand-file-name file))
- (if (file-directory-p file)
- (setq file (concat file "DOC")))
- (setq doc-file-name file)
- (load (concat file "-keys.el")))
-
- (defun require-doc-file()
- (or doc-file-name
- (visit-doc-file (read-file-name "Visit doc table: (default DOC) "
- default-directory
- (concat default-directory "DOC")
- t))))
- (defvar find-doc-edit nil "If non nil, instead of just printing out
- a copy of the documentation in the other window, we actually visit
- the DOC file. This is useful for editing it.")
- (defun find-doc()
- (interactive)
- (require-doc-file)
- (require 'sshell)
-
- (or find-doc-edit(and find-doc-buffer (get-buffer-process find-doc-buffer))
- (progn (setq find-doc-buffer
- (make-shell "find-doc"
- "/bin/sh" nil "-i"))
- (sleep-for 2)
- (send-string (get-buffer-process find-doc-buffer)
- "PS1=\n \n")
- ))
-
- (let (tem result (completion-ignore-case t))
- (save-excursion
- (condition-case er
- (progn
- (forward-sexp -1)
- (setq tem
- (buffer-substring (point) (progn (forward-sexp 1) (point)))))
- (error)))
- (or (and tem (assoc (setq tem (upcase tem)) my-lisp-doc))
- (setq tem nil))
- (let ((symbol (completing-read "Describe symbol: "
- my-lisp-doc nil t tem)))
- (setq result (assoc symbol my-lisp-doc))
- (or result
- (setq result (assoc (downcase symbol) my-lisp-doc)))
- (or result
- (setq result (assoc (upcase symbol) my-lisp-doc)))
- (or result (error (format "case mix up: %s not in my-lisp-doc keys" symbol))))
-
-
- (cond (find-doc-edit
- (find-file-other-window doc-file-name)
- (goto-char (cdr result))
- (set-fill-column 79)
- (cond ((looking-at (concat "[A-Z]"
- (car result)))
- (recenter 0)
- )
- (t (goto-char (point-min))
- (re-search-forward (concat "[A-Z\n]" (car result) "\\b"))
- (recenter 0)
- ))
- )
- ( t
- (let ((old (current-buffer)))
- (switch-to-buffer find-doc-buffer)
- (erase-buffer)
- (goto-char (point-max))
- (send-string (get-buffer-process find-doc-buffer)
- "echo Documentation: \n"
- )
-
- (process-send-string (get-buffer-process find-doc-buffer)
- (format "print_doc %s %d \n"
- doc-file-name (cdr result)))
- (switch-to-buffer old)
-
- (display-buffer find-doc-buffer)
- result)))))
-
-
- ;;common lisp for creating a doc file.
-
-
-
- (defun doc-file (file packages)
- ;;Write FILE of doc strings for all symbols in PACKAGES
- ;;This file is suitable for use with the find-doc function.
- (with-open-file (st file :direction :output)
- (sloop:sloop
- for v in packages
- do (sloop:sloop
- for w in-package (if (packagep v) (package-name v) v)
- when (setq doc (documentation w 'function))
- do (format st "F~a~%~a~a" w
- (cond ((special-form-p w) "Special Form: ")
- ((functionp w) "Function: ")
- ((macro-function w) "Macro: ")
- (t ""))
- doc)
- when (setq doc (documentation w 'variable))
- do (format st "VVariable:~a~%~a" w doc)
- ))))
-
-